/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2002 - 2007 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package flex.messaging.security;

import flex.messaging.MessageException;
import flex.messaging.log.LogEvent;
import flex.messaging.messages.ErrorMessage;
import flex.messaging.messages.Message;
import flex.messaging.util.ResourceLoader;

/**
 * SecurityException is a localizable exception type that is used to represent
 * client authentication, client authorization and general server-related security
 * errors. It defines a set of supported error code values as constants suffixed
 * with _CODE.
 * 
 * @author Peter Farland
 * @author Seth Hodgson
 */
public class SecurityException extends MessageException
{
    static final long serialVersionUID = -3168212117963624230L;

    // Error code constants.
    public static final String CLIENT_AUTHENTICATION_CODE = "Client.Authentication";
    public static final String CLIENT_AUTHORIZATION_CODE = "Client.Authorization";
    public static final String SERVER_AUTHENTICATION_CODE = "Server.Authentication";
    public static final String SERVER_AUTHORIZATION_CODE = "Server.Authorization";

    //--------------------------------------------------------------------------
    //
    // Constructors
    //
    //--------------------------------------------------------------------------    
    
    /**
     * Create a SecurityException that will use the default ResourceLoader
     * for error codes.
     */
    public SecurityException()
    {
        super();
    }
    
    /**
     * Create a SecurityException that will use the specified ResourceLoader
     * for error codes.
     * 
     * @exclude
     */
    public SecurityException(ResourceLoader resourceLoader)
    {
        super(resourceLoader);
    }

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------        
    
    //----------------------------------
    //  defaultLogMessageIntro
    //----------------------------------            

    /**
     * @exclude
     * Returns the default initial text for the log output generated by <code>logAtHingePoint()</code>.
     */
    public String getDefaultLogMessageIntro()
    {
        return "Security error for message: ";
    }  
    
    //----------------------------------
    //  logStackTraceEnabled
    //----------------------------------            
    
    /**
     * @exclude
     * Override to disable stack trace logging. Security exceptions are generally innocuous (invalid credentials/role membership)
     * and stack traces make these faults scarier than necessary.
     */
    public boolean isLogStackTraceEnabled()
    {
        return false;
    }    
    
    //----------------------------------
    //  peferredLogLevel
    //----------------------------------            
    
    /**
     * @exclude
     * Returns the preferred log level for this exception instance.
     */
    public short getPreferredLogLevel()
    {
        // SecurityExceptions are common, incorrect credentials/invalid role membership, and don't
        // need to be logged at the ERROR level.
        return LogEvent.DEBUG;        
    } 
    
    //----------------------------------
    //  failingMessage
    //----------------------------------            
    
    private Message failingMessage;
    
    /**
     * Returns the message with information about what caused this security exception to be thrown.
     * 
     * @return message with information about what caused this security exception to be thrown
     */
    public Message getFailingMessage()
    {
        return failingMessage;
    }

    /**
     * Sets the message with information about what caused this security exception to be thrown.
     * 
     * @param failingMessage message with information about what caused this security exception to be thrown
     */
    public void setFailingMessage(Message failingMessage)
    {
        this.failingMessage = failingMessage;
    }

    //--------------------------------------------------------------------------
    //
    // Public Methods
    //
    //--------------------------------------------------------------------------    
    
    /**
     * Overrides <code>createErrorMessage()</code> to correlate the <code>ErrorMessage</code> to the
     * failing message by id and destination.
     * 
     * @return correlated error message
     */
    public ErrorMessage createErrorMessage()
    {
        ErrorMessage msg = super.createErrorMessage();
        if (failingMessage != null)
        {
            msg.setCorrelationId(failingMessage.getMessageId());
            msg.setDestination(failingMessage.getDestination());
        }
        return msg;
    } 
}